﻿using System;
using System.Collections.Generic;
using System.Text;
using SourceCode.Workflow.Management;
using SourceCode.Workflow.Management.Criteria;
using SourceCode.Hosting.Client.BaseAPI;

namespace ASBCC.Workflow.K2Manager
{
    public static class K2Admin
    {
        /// <summary>
        /// 获取processName流程中，指定folio值的所有WorklistItem
        /// WorklistItem.ID在这个WorklistItem被Open过之前始终为0
        /// 可以通过WorklistItem.ProcInstID + WorklistItem.ActInstDestID + WorklistItem.Destination作为WorklistItem的唯一标识
        /// WorklistItem的SerialNumber= string.
        /// </summary>
        /// <param name="processName"></param>
        /// <param name="folio"></param>
        /// <returns></returns>
        public static WorklistItems GetWorklistItems(string processName, string folio)
        {
            WorkflowManagementServer server = GetWorkflowManagementServer();
            try
            {
                //modify by dengtk 20100609
                //return server.GetWorklistItems("", processName, "", "", folio, "", "");
                SourceCode.Workflow.Management.WorklistItems worklistItems = server.GetWorklistItems("", processName, "", "", folio, "", "");
                
                for (int i = 0; i < K2Config.K2GetWoekItemRetryTimes; i++)
                {
                    if (worklistItems.Count > 0)
                    {
                        break;
                    }
                    System.Threading.Thread.Sleep(K2Config.K2GetWorkItemDelaySecond * 1000);
                    worklistItems = server.GetWorklistItems("", processName, "", "", folio, "", "");
                }
                return worklistItems;
            }
            finally
            {
                if (server.Connection != null) server.Connection.Close();
            }
        }

        /// <summary>
        /// 将WorklistItem从一个人手里转到另外一个人
        /// </summary>
        /// <param name="fromUserName"></param>
        /// <param name="toUserName">目标用户名如K2:AD4/Chunleih</param>
        /// <param name="procInstID"></param>
        /// <param name="actInstDestID"></param>
        /// <param name="worklistItemID">可以为0</param>
        public static void RedirectWorklistItem(string fromUserName, string toUserName, int procInstID, int actInstDestID, int worklistItemID)
        {
            WorkflowManagementServer server = GetWorkflowManagementServer();
            try
            {
                bool res = (bool)server.RedirectWorklistItem(fromUserName, toUserName, procInstID, actInstDestID, worklistItemID);
                if (!res) throw new Exception(string.Format("Failed to RedirectWorklistItem. fromUserName={0}; toUserName={1} procInstID={2}; actInstDestID={3}; worklistItemID={4}", fromUserName, toUserName, procInstID, actInstDestID, worklistItemID));
            }
            finally
            {
                if (server.Connection != null) server.Connection.Close();
            }
        }

        public static void GotoActivity(int procInstId, string activityName)
        {
            WorkflowManagementServer server = GetWorkflowManagementServer();
            try
            {
                server.GotoActivity(procInstId, activityName);
            }
            finally
            {
                if (server.Connection != null) server.Connection.Close();
            }
        }

        /// <summary>
        /// 获取指定ProcessName的默认流程版本
        /// </summary>
        /// <param name="processName"></param>
        /// <returns></returns>
        public static int GetDefaultVersionNumber(string processName)
        {
            Process process = GetDefaultProcess(processName);
            if (process == null) return -1;
            return process.VersionNumber;
        }

        public static int GetDefaultProcID(string processName)
        {
            Process process = GetDefaultProcess(processName);
            if (process == null) return -1;
            return process.ProcID;
        }

        /// <summary>
        /// 获取指定procInstID对应的流程版本
        /// </summary>
        /// <param name="procInstID"></param>
        /// <returns></returns>
        public static int GetVersionNumber(int procInstID)
        {
            Process process = GetProcess(procInstID);
            if (process == null) return -1;
            return process.VersionNumber;
        }

        public static int GetProcID(int procInstID)
        {
            return K2DataHelper.GetProcID(procInstID);
        }

        //public static int GetProcID(int procInstID)
        //{
        //    Process process = GetProcess(procInstID);
        //    if (process == null) return -1;
        //    return process.ProcID;
        //}

        //public static int GetProcID(int procId, string folio, int procInstID)
        //{
        //    Process process = GetProcess(procId, folio, procInstID);
        //    if (process == null) return -1;
        //    return process.ProcID;
        //}

        private static WorkflowManagementServer GetWorkflowManagementServer()
        {
            SCConnectionStringBuilder connectionString = new SCConnectionStringBuilder();
            connectionString.Authenticate = true;
            connectionString.Host = K2Config.K2Server;
            connectionString.Integrated = true;
            connectionString.IsPrimaryLogin = true;
            connectionString.Port = K2Config.K2MgmtPort;
            connectionString.WindowsDomain = K2Config.K2DomainName;
            connectionString.UserID = K2Config.K2AdminName;
            connectionString.Password = K2Config.K2AdminPassword;

            WorkflowManagementServer server = new WorkflowManagementServer();
            server.CreateConnection();
            server.Connection.Open(connectionString.ToString());
            return server;
        }

        /// <summary>
        /// 获取指定ProcessName的默认Process对象
        /// </summary>
        /// <param name="processName"></param>
        /// <returns></returns>
        public static Process GetDefaultProcess(string processName)
        {
            WorkflowManagementServer server = GetWorkflowManagementServer();
            try
            {
                ProcessSets processSets = server.GetProcSets();
                ProcessSet foundProcessSet = null;
                foreach (ProcessSet processSet in processSets)
                {
                    if (string.Compare(processSet.FullName, processName, true) == 0)
                    {
                        foundProcessSet = processSet;
                    }
                }

                if (foundProcessSet == null) return null;

                Processes processes = server.GetProcessVersions(foundProcessSet.ProcSetID);
                foreach (Process process in processes)
                {
                    if (process.DefaultVersion) return process;
                }
                return null;
            }
            finally
            {
                if (server.Connection != null) server.Connection.Close();
            }
        }

        public static Process GetProcess(int procInstId)
        {
            ProcessInstance procInst = GetProcessInstance(procInstId);
            if (procInst == null) return null;
            return procInst.Process;
        }

        public static ProcessInstance GetProcessInstance(int procInstId)
        {
            //Can't work

            WorkflowManagementServer server = GetWorkflowManagementServer();
            try
            {
                ProcessInstanceCriteriaFilter filter;
                filter = new ProcessInstanceCriteriaFilter();
                filter.AddRegularFilter(ProcessInstanceFields.ProcInstID, Comparison.Equals, procInstId);
                ProcessInstances procInsts = server.GetProcessInstancesAll(filter);
                if (procInstId <= 0 || procInsts.Count == 0) return null;
                return procInsts[0];
            }
            finally
            {
                if (server.Connection != null) server.Connection.Close();
            }
        }
    }
}
